package com.hk.commons.query;


import com.hk.commons.util.ArrayUtils;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.core.ResolvableType;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;


/**
 * queryModel
 */
@Data
public class QueryModel<T> {

    public static final int DEFAULT_PAGE_INDEX = 0;

    public static final int DEFAULT_PAGE_SIZE = 10;

    public static final int MAX_PAGE_SIZE = 200;

    /**
     * 查询分页参数
     */
    private int pageIndex;

    /**
     * 查询分页参数，默认为10
     */
    private int pageSize = DEFAULT_PAGE_SIZE;

    /**
     * 分页时，不需要再count，所以用该属性来存上一次count的数字
     */
    private int totalRowCount;

    /**
     * 查询参数
     */
    private T param;

    /**
     * 查询排序
     */
    private List<Order> orders = new ArrayList<>();

    public final int getStartRowIndex() {
        return pageIndex <= 0 ? DEFAULT_PAGE_INDEX : pageIndex - 1;
    }

    public T getParam() {
        if (Objects.isNull(param)) {
            var resolvableType = ResolvableType.forClass(QueryModel.class);
            @SuppressWarnings("unchecked")
            var resolve = (Class<T>) resolvableType.getGeneric(0).resolve();
            if (Objects.nonNull(resolve)) {
                param = BeanUtils.instantiateClass(resolve);
            }
        }
        return param;
    }

    /**
     * 不能小于等于0
     *
     * @return pageSize
     */
    public final int getPageSize() {
        return pageSize <= 0 ? DEFAULT_PAGE_SIZE : Math.min(this.pageSize, MAX_PAGE_SIZE);
    }

    /**
     * 添加排序到第一个
     *
     * @param order order
     * @return {@link QueryModel}
     */
    public QueryModel<T> addOrderToFirst(Order order) {
        this.orders.addFirst(order);
        return this;
    }

    /**
     * 添加排序
     *
     * @param orders Orders
     * @return {@link QueryModel}
     */
    public QueryModel<T> addOrders(Order... orders) {
        this.orders.addAll(ArrayUtils.asArrayList(orders));
        return this;
    }

    /**
     * 添加排序
     *
     * @param orders Orders
     * @return {@link QueryModel}
     */
    public QueryModel<T> addOrders(Collection<Order> orders) {
        this.orders.addAll(orders);
        return this;
    }
}
